<template>
  <div
    id="hlsPlayer-container"
    class="hlsPlayer-container"
    @mouseenter="controlsShow = true"
    @mouseleave="mouseleave"
    @mousemove="controlsShow = true"
  >
    <div class="loading">
      <h6
        v-loading="loading"
        element-loading-background="rgba(0, 0, 0, 0.1)"
        element-loading-text="正在缓冲"
      ></h6>
    </div>
    <video
      ref="videoPlayer"
      id="videoPlayer"
      preload="auto"
      @click="clickVideo"
      @dblclick="dblClickVideo"
      @ended="videoEnd"
      @play="videoStatus = true"
      @pause="videoStatus = false"
    ></video>
    <div id="controls" class="controls" v-if="controlsShow">
      <i
        class="el-icon-video-play"
        style="font-size: 0.125rem"
        v-if="!videoStatus"
        @click="clickVideo"
      ></i>
      <i
        style="font-size: 0.125rem"
        class="el-icon-video-pause"
        v-if="videoStatus"
        @click="clickVideo"
      ></i>
      <!-- 总时间/剩余时间 -->
      {{ formatTime(currentTime) }} / {{ formatTime(videodDuration) }}
      <br />
      <!-- 进度条 -->
      <el-slider
        class="sidebarProgress"
        v-model="currentTime"
        :format-tooltip="formatTime"
        @change="currentTimeChange"
        @input="currentTimeInput"
        @click="sliderClick"
        :min="0"
        :max="videodDuration"
        style="width: 60%"
      />
      <el-dropdown placement="top" popper-class="levelClass v">
        <span class="el-dropdown-link" @click="toMute">
          <img style="width: 0.125rem" src="@/assets/icon/音量大小.svg" alt="" v-if="muted" />
          <img style="width: 0.125rem" src="@/assets/icon/关闭音量.svg" alt="" v-if="!muted" />
        </span>
        <!-- 音量 -->
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item>
              <el-slider
                class="volume"
                v-model="volume"
                vertical
                height="0.5208rem"
                :min="0"
                :max="100"
                @change="volumeChange"
                @input="volumeChange"
                tooltip-class="progressTips"
              />
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <!-- 清晰度 -->
      <el-dropdown placement="top" @command="changeQuality" popper-class="levelClass">
        <span class="el-dropdown-link"> {{ qualityName }} </span>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item
              v-for="(level, index) in qualityLevels"
              :key="index"
              :value="index"
              :command="level"
            >
              {{ level.resolution }}
            </el-dropdown-item>
            <el-dropdown-item :command="{ resolution: '自动', index: -1 }"> 自动 </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <el-dropdown placement="top" @command="changeSpeed" popper-class="levelClass">
        <span class="el-dropdown-link"> {{ videoSpeed + 'x' }} </span>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item
              v-for="(item, index) in speedArr"
              :key="index"
              :value="index"
              :command="item"
            >
              {{ item }}x
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <i style="font-size: 0.125rem" class="el-icon-full-screen" @click="dblClickVideo"></i>
    </div>
  </div>
</template>
<script>
import Hls from 'hls.js'
import { keepTime } from '@/api/index'
export default {
  props: ['masterUrlRef', 'watchtime'],
  data() {
    return {
      lock: false,
      loading: true,
      hls: null,
      controlsShow: true,
      timeoutId: null,
      timeoutId2: null, //
      hlsPlayerContainer: null,
      // 视频播放状态
      videoStatus: false,
      // 播放的时长
      currentTime: 0,
      // 已缓存时长
      BufferedTime: 0,
      // 视频总时长
      videodDuration: 0,
      // 存储各个分辨率信息
      qualityLevels: [],
      // -1 表示自动
      selectedQuality: -1,
      // 分辨率名称
      qualityName: '自动',
      // 播放速度
      videoSpeed: 1,
      speedArr: [3, 2.5, 2, 1.5, 1, 0.5],
      // 音量
      volume: 100,
      lastVolume: 10,
      muted: false,
      // 样式
      theme: {
        progress: '90%'
      }
    }
  },

  // 监听器
  watch: {
    masterUrlRef() {
      this.hlsDestroy()
      this.videoInit()
      this.hlsInit()
      this.$refs.videoPlayer.play()
    }
  },
  mounted() {
    window.addEventListener('mousemove', this.resetTimer)
    this.hlsPlayerContainer = document.getElementById('hlsPlayer-container')
    // let videoPlayer = document.getElementById('videoPlayer')
    this.resetTimer() // 触发初始倒计时
    this.hlsDestroy()
    this.hlsInit()

    this.muted = localStorage.getItem('muted') ?? false
    this.lastVolume = localStorage.getItem('lastVolume')
    this.volume = Number(localStorage.getItem('volume')) ?? 100
    this.$refs.videoPlayer.volume = this.volume / 100

    // 监听加载
    this.$refs.videoPlayer.addEventListener('loadedmetadata', () => {
      if (this.watchtime >= parseInt(this.$refs.videoPlayer.duration)) {
        this.$refs.videoPlayer.currentTime = 0
      } else {
        this.watchtime ? (this.$refs.videoPlayer.currentTime = this.watchtime) : ''
      }
      this.videodDuration = this.$refs.videoPlayer.duration

      this.$refs.videoPlayer.volume = this.volume / 100
    })
    // 监听播放进度
    this.$refs.videoPlayer.addEventListener('timeupdate', () => {
      this.currentTime = this.$refs.videoPlayer.currentTime
      this.setBuffer()
      if (
        parseInt(this.$refs.videoPlayer.currentTime) % 15 == 0 &&
        parseInt(this.$refs.videoPlayer.currentTime) != 0
      ) {
        this.keepTime(parseInt(this.$refs.videoPlayer.currentTime))
      }
    })
    // 监听缓存进度
    this.$refs.videoPlayer.addEventListener('progress', () => {
      if (
        this.$refs.videoPlayer &&
        this.$refs.videoPlayer.buffered &&
        this.$refs.videoPlayer.buffered.length > 0
      ) {
        const lastBufferedTime = this.$refs.videoPlayer.buffered.end(
          this.$refs.videoPlayer.buffered.length - 1
        )
        this.BufferedTime = lastBufferedTime
        this.theme.progress = (this.BufferedTime / this.videodDuration) * 100 + '%'
      }
      this.setBuffer()
    })
    // 监听音量
    // this.$refs.videoPlayer.addEventListener('volumechange', () => {
    //   // 更新当前音量
    //   if (this.volume == 0) {
    //     this.muted = false
    //     localStorage.setItem('muted', this.muted)
    //   } else {
    //     this.muted = true
    //     localStorage.setItem('muted', this.muted)
    //   }
    // })
  },
  methods: {
    // 缓冲进度与播放进度相等就显示加载图标
    setBuffer() {
      if (parseInt(this.$refs.videoPlayer.currentTime) >= parseInt(this.BufferedTime)) {
        this.loading = true
      } else {
        this.loading = false
      }
    },
    // 视频初始化
    videoInit() {
      this.currentTime = 0
      this.BufferedTime = 0
      this.videodDuration = 0
      this.qualityLevels = []
      this.selectedQuality = -1
      this.qualityName = '自动'
      this.videoSpeed = 1
      this.$refs.videoPlayer.playbackRate = 1
    },
    // hls初始化
    hlsInit() {
      // 加载视频
      if (Hls.isSupported() || navigator.userAgent.includes('Safari')) {
        const hls = new Hls({
          xhrSetup: xhr => {
            xhr.setRequestHeader('x-auth', localStorage.getItem('token'))
          }
        })
        this.hls = hls
        hls.loadSource(this.masterUrlRef)
        hls.attachMedia(this.$refs.videoPlayer)
        hls.on(Hls.Events.MANIFEST_PARSED, () => {
          // 提取各个质量层级信息
          this.qualityLevels = hls.levels.map((level, index) => {
            let resolution = ''
            // 如果 hls.js 已经提供 height，就直接用
            if (level.height) {
              resolution = level.height + 'p'
            } else if (level.url && level.url.length > 0) {
              // 如果没有 height，从 TS 文件名中解析 (例如 stream_360_004.ts)
              const match = level.url[0].split('_')
              if (match && match[1]) {
                resolution = match[1].replace('.m3u8', '') + 'P'
              } else {
                resolution = '未知'
              }
            } else {
              resolution = '未知'
            }
            return {
              resolution,
              index // 这里的 index 与 hlsInstance.levels 中的顺序对应
            }
          })
          this.selectedQuality = -1 // 默认自动模式
          this.qualityLevels.sort((a, b) => {
            return parseInt(b.resolution.replace('P', '')) - parseInt(a.resolution.replace('p', ''))
          })
        })
      } else {
        // 兜底
        this.$refs.videoPlayer.src = this.masterUrlRef
      }
    },
    // 销毁hls
    hlsDestroy() {
      if (this.hls) {
        this.hls.destroy()
        this.hls = null // 避免引用残留
      }
    },
    // 单击视频
    clickVideo() {
      if (this.$refs.videoPlayer.paused) {
        this.$refs.videoPlayer.play()
      } else {
        this.$refs.videoPlayer.pause()
      }
    },
    // 双击视频
    dblClickVideo() {
      if (!document.fullscreenElement) {
        // 如果当前没有全屏元素，则让 hlsPlayerContainer 进入全屏
        this.hlsPlayerContainer.requestFullscreen().catch(err => {
          console.error('进入全屏失败:', err)
        })
      } else {
        // 如果当前有全屏元素，则退出全屏
        document.exitFullscreen().catch(err => {
          console.error('退出全屏失败:', err)
        })
      }
    },
    // 进度条
    async currentTimeChange(e) {
      if (!this.$refs.videoPlayer.paused) {
        await this.$refs.videoPlayer.pause()
      }
      this.$refs.videoPlayer.currentTime = e
      this.$refs.videoPlayer.play()
    },
    // 拖动进度条
    currentTimeInput(e) {
      // if (!this.$refs.videoPlayer.paused) {
      //   this.$refs.videoPlayer.pause()
      // }
      // this.$refs.videoPlayer.currentTime = e
    },
    // 点击进度条
    sliderClick() {
      if (!this.$refs.videoPlayer.paused) {
        this.$refs.videoPlayer.pause()
      }
    },
    // 音量条
    volumeChange(val) {
      // 更新当前音量
      if (this.volume == 0) {
        this.muted = false
        localStorage.setItem('muted', this.muted)
      } else {
        this.muted = true
        localStorage.setItem('muted', this.muted)
      }
      this.volume = val
      localStorage.setItem('volume', val)
      // 不是静音的情况下保存当前音量
      if (this.muted) {
        localStorage.setItem('lastVolume', val)
      }
      this.$refs.videoPlayer.volume = val / 100
    },
    // 分辨率改变
    changeQuality(level) {
      this.qualityName = level.resolution
      this.selectedQuality = level.index
      if (!this.$refs.videoPlayer.paused) {
        this.$refs.videoPlayer.pause()
      }
      if (this.hls) {
        this.hls.currentLevel = this.selectedQuality // 手动指定
      }
      if (this.$refs.videoPlayer.paused) {
        this.$refs.videoPlayer.play()
      }
    },
    // 播放速度改变
    changeSpeed(speed) {
      this.videoSpeed = speed
      this.$refs.videoPlayer.playbackRate = speed
    },
    // 监听鼠标移动
    resetTimer() {
      if (this.timeoutId) {
        clearTimeout(this.timeoutId)
      }
      this.timeoutId = setTimeout(() => {
        this.controlsShow = false // 2秒后隐藏
      }, 2000)
    },

    // 鼠标移出
    mouseleave() {
      if (this.timeoutId2) {
        clearTimeout(this.timeoutId2)
      }
      this.timeoutId2 = setTimeout(() => {
        this.controlsShow = false // 2秒后隐藏
      }, 2000)
    },
    toMute() {
      if (this.muted) {
        // 静音
        this.muted = false
        this.volume = 0
      } else {
        // 非静音
        this.muted = true
        this.volume = 45
      }
      localStorage.setItem('volume', this.volume)
      localStorage.setItem('muted', this.muted)
      this.$refs.videoPlayer.volume = this.volume / 100
    },
    // 监听视频播放结束
    videoEnd() {
      this.loading = false
      let catalogId = localStorage.getItem('catalogId')
      // 通知父组件
      this.$emit('videoEnded', catalogId)
    },
    // 间隔一段时间调用 保存观看的进度
    async keepTime(time) {
      if (this.lock) return
      this.lock = true
      let params = {
        catalogId: localStorage.getItem('catalogId'),
        time: time
      }
      let res = await keepTime(params)
      if (res.code == 100) {
        setTimeout(() => {
          this.lock = false
        }, 1000)
      }
    },
    // 时间格式化
    formatTime(seconds) {
      if (isNaN(seconds) || seconds < 0) return '00:00' // 处理 NaN 和负数情况
      const minutes = Math.floor(seconds / 60) // 直接计算总分钟数
      const secs = Math.floor(seconds % 60)
      return `${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`
    }
  }
}
</script>

<style lang="scss" scoped>
.hlsPlayer-container {
  width: 100%;
  background-color: rgba(255, 255, 255, 0);
  position: relative;
  display: flex;
  justify-content: center;
  align-self: center;
  .loading {
    position: absolute;
    width: 100%;
    height: 100%;
    h6 {
      width: 100%;
      height: 90%;
    }
  }
  video {
    width: 100%;
    margin: 0;
    padding: 0;
  }
  .controls {
    width: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    margin: 0;
    padding: 0;
    height: 0.3125rem;
    position: absolute;
    color: white;
    bottom: 0rem;
    display: flex;
    align-items: center;
    justify-content: space-around;
  }
}

/* 进度条 */
:deep(.el-dropdown) {
  color: white;
}

:deep(.el-slider__bar) {
  border-radius: 0;
}

:deep(.el-slider__runway) {
  border-radius: 0;
  &:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: v-bind('theme.progress');
    height: 100%;
    background: rgb(180, 183, 183);
  }
}
.el-slider.sidebarProgress {
  width: 5%;
  transition: width 0.2s ease-in-out;
  .el-slider__runway {
    width: 0.0208rem;
  }
  .el-slider__bar {
    width: 0.0208rem;
  }
  &:hover {
    width: 10%;
  }
  :deep(.el-slider__button) {
    border: none;
    border-radius: 0.0052rem;
    width: 0.0417rem;
    height: 0.0573rem;
  }

  :golbal(.progressTips) {
    * {
      color: green;
    }
  }
}
.el-slider.volume {
  width: 5%;
  transition: width 0.2s ease-in-out;
  .el-slider__runway {
    width: 0.0208rem;
  }
  .el-slider__bar {
    width: 0.0208rem;
  }
  &:hover {
    width: 10%;
  }
  :deep(.el-slider__button) {
    border: none;
    border-radius: 0.0052rem;
    width: 0.0417rem;
    height: 0.0573rem;
  }

  :golbal(.progressTips) {
    * {
      color: green;
    }
  }
}
::v-deep .el-loading-spinner .el-loading-text {
  color: #fff;
}
::v-deep .el-loading-mask {
  z-index: 10;
}
</style>
<style lang="scss">
.levelClass {
  --el-bg-color-overlay: rgba(0, 0, 0, 0.5);
  --el-border-color-light: rgba(0, 0, 0, 0);
  --el-dropdown-menuItem-hover-fill: #333;
  --el-dropdown-menuItem-hover-color: white;
  background-color: rgba(0, 0, 0, 0);
  .el-dropdown__popper.el-popper {
    border: none;
    box-shadow: none;
  }
  :deep(.el-dropdown-menu) {
    background-color: rgba(0, 0, 0, 0);
  }
  .el-dropdown-menu__item {
    color: white;
  }
}
.levelClass.v {
  --el-dropdown-menuItem-hover-fill: rgba(0, 0, 0, 0);
}
</style>
